-- Base Function

/*
fn Fn_Round num = 
(
	remainder = num- (floor num)
	if (remainder >= .5) then (fnum= ceil num) else (fnum = floor num) 
	fnum
)
*/

fn Fn_Clamp num cMin cMax = 
(
	result = num
	if result < cMin then
	(
		result = cMin
	)
	else
	(
		if result > cMax then 
		(
			result = cMax
		)
	)
	return result
)

/*
fn Fn_ClampVector V vMin vMax =
(
	tempvector=[0.0,0.0,0.0] 
	for a=1 to 3 do (
		tempvector[a]=clamp V[a] vMin vMax
	)
	tempvector
)
	
fn Fn_AbsoluteValVector V =
(
	tempvector=[0.0,0.0,0.0] 
	for a=1 to 3 do (
		tempvector[a]=abs V[a] 
	)
	tempvector
)
*/

-- A2U_Function
struct A2U_FbxParams
(
	FileVersion = "FBX201600",
	ASCII = "false",

	SmoothingGroups = "true",
	NormalsPerPoly = "false",
	TangentSpaceExport = "true",
	GeomAsBone = "true",
	Triangulate= "true",
	PreserveEdgeOrientation = "false",

	Resampling = "60.0",
	Skin = "true",
	Shape = "true",

	Cameras = "false",
	Lights = "false",

	EmbedTextures = "false",
	CAT2HIK = "false",
	UpAxis = "Z"
)

fn A2UFn_IsBoneOrBiped obj = 
(
	if (isKindOf obj Biped_Object) or (isKindOf obj BoneGeometry) or (isKindOf obj helper) or ((isKindOf obj shape) and obj.boneEnable == true) then
		return true
	else
		return false
)

struct A2U_AnimClipParams
(
	AnimName,
	AnimRangeStart,
	AnimRangeEnd
)

fn A2UFn_GetAnimClips =
(
	local animClipArray = #()

	local ttCount = FrameTagManager.GetTagCount()
	if ttCount > 0 then
	(
		for i = 1 to ttCount do
		(
			local str_tt = FrameTagManager.GetNameByID i
			if matchPattern str_tt pattern:"*#*" then
			(
				local a_tt = (filterString str_tt "#")
				local animName = a_tt[1]
				local animRangeStart = FrameTagManager.GetTimeByID i
				local animRangeEnd = a_tt[2] as time
				if animRangeStart < animRangeEnd then
				(
					local animClip = A2U_AnimClipParams AnimName:animName AnimRangeStart:animRangeStart AnimRangeEnd:animRangeEnd
					append animClipArray animClip
				)
			)
		)
	)

	return animClipArray
)

fn A2UFn_IsNotExport obj =
(
	local IsNotExport = getUserProp obj "aurogon_fbx_export_as" == "noexport"
	
	-- 在Gujian4环境下 *origin 不导出
	if A2UFn_IsWorkSpace_Gujian4() and (obj.name == "*origin") then
		IsNotExport = true
	
	-- *skelid 不导出
	if (obj.name == "*skelid") then
		IsNotExport = true
	
	return IsNotExport
)

fn A2UFn_IsExportSkeletalMesh geo skelName = 
(
	local IsCloth = matchPattern geo.name pattern:"*#cloth*"
	local IsSkelPlaneMesh = (geo.name == skelName)	-- 骨架自带面片 不导出
	local IsNotExport = A2UFn_IsNotExport geo
	local IsBoneOrBiped = A2UFn_IsBoneOrBiped geo
	local IsHaveSkinModifier = geo.modifiers[Skin] != undefined
	local IsNamingValid = findstring geo.name "SK_" != undefined

	-- note: 按需扩展
	-- 目前导出规则：
	-- 名字带 "SK_"
	-- 包含Skin修改器
	-- not 隐藏
	-- not 属性为不导出
	-- not 布料（布料需要跟着其他geo一起导出）
	-- not 骨架名box
	-- not Bone/Biped物体
	-- 是 mesh/poly/polymeshobject(带有修改器的mesh) 的一种

	return not geo.isHidden and IsHaveSkinModifier and IsNamingValid and
			not IsNotExport and not IsCloth and not IsSkelPlaneMesh and not IsBoneOrBiped and
			(iskindof geo editable_mesh or iskindof geo editable_poly or iskindof geo polymeshobject)
)

fn A2UFn_GenerateSMFilename bAll =
(
	local objs = selection
	if bAll then (objs = geometry)

	for obj in objs do 
	(
		if (isKindOf obj GeometryClass) then
		(
			if not obj.isHidden and findstring obj.name "_" != undefined and
				--not IsNothing and not IsCloth and not IsSkelPlaneMesh and
				(iskindof obj editable_mesh or iskindof obj editable_poly or iskindof obj polymeshobject) then
			(
				return obj.name
			)
		)
	)

	return ""
)

-- 选相关联的布料代理模型（隐藏的不选择）
fn A2UFn_SelectRelateClothMesh ingeo = 
(
	selectMore ingeo

	for geo in geometry do 
	(
		local geoName = ingeo.name
		local strClothMatch = ingeo.name + "#cloth*"

		if (matchPattern geo.name pattern:strClothMatch) and (not geo.isHidden) then
		(
			selectMore geo
		)
	)
)

fn __traversalChildNode parentNode selectionArray = 
(
	if parentNode == undefined then
	(
		return false
	)

	for childnode in parentNode.children do
	(
		if childnode.children.count > 0 then
		(
			if not (__traversalChildNode childnode selectionArray) then
			(
				return false
			)
		)
		else
		(
			append selectionArray childnode
			print(childnode.name)
		)
	)

	append selectionArray parentNode
	print(parentNode.name)
	
	return true
)

fn __traversalChildSkelNode parentNode selectionArray = 
(
	if parentNode == undefined then
	(
		--hlog_error("hfn_selectSkeletonAll: parentNode is undefined")
		return false
	)

	for childnode in parentNode.children do
	(
		if childnode.children.count > 0 then
		(
			if not (__traversalChildSkelNode childnode selectionArray) then
				return false
		)
		else
		(
			if not (A2UFn_IsNotExport childnode) and (A2UFn_IsBoneOrBiped childNode) then
			(
				append selectionArray childnode
			)
		)
	)

	-- handle the parent node
	if not (A2UFn_IsNotExport parentNode) and (A2UFn_IsBoneOrBiped parentNode) then
	(
		append selectionArray parentNode
	)
	
	return true
)

fn A2UFn_IsBip01RootObject node = 
(
	-- if node == undefined then return false
	-- local ret = false
	-- if ClassOf(node) == Biped_Object and ClassOf(node.Controller) == Vertical_Horizontal_Turn then
	-- 	ret = true
	-- return ret
	if node == undefined then return false
	return node.name == "Bip01"
)

fn A2UFn_IsSkelRootObject node = 
(
	if node == undefined then return false
	local ret = false
	if ClassOf(node) == Dummy and node.name == "Root" then
	(
		for _child in node.children do
		(
			if _child.name == "Bip01" then
				ret = true
		)
	)
	return ret
)

fn A2UFn_IsOriginNodeObject node = 
(
	if node == undefined then return false
	local ret = false
	if ClassOf(node) == Dummy and node.name == "*origin" then
	(
		local _nodeParent = node.parent
		if A2UFn_IsSkelRootObject(_nodeParent) then
			ret = true
	)
	return ret
)

fn A2UFn_IsCamera node = 
(
	return (findItem ($Cameras as Array) node > 0) and (isKindOf node camera)
)

fn A2UFn_IsCameraTarget node = 
(
	return (findItem ($Cameras as Array) node > 0) and (not (isKindOf node camera))
)

fn A2UFn_IsCameraOrCameraTarget node = 
(
	return (findItem ($Cameras as Array) node > 0)
)

fn A2UFn_GetAllBipedObject = 
(
	local bipedObjects = #()
	for geo in geometry where (isKindOf geo Biped_Object) do
	(
		append bipedObjects geo
	)
	return bipedObjects
)

fn A2UFn_GetAllBoneObject = 
(
	local boneObjects = #()
	for geo in geometry where (isKindOf geo BoneGeometry) do
	(
		append boneObjects geo
	)
	return boneObjects
)

fn A2UFn_GetAllShape = 
(
	return shapes
)

fn A2UFn_GetAllShapeUseAsBone = 
(
	local shapeAsBone = #()
	for curShape in shapes where shape.boneEnable == true do
	(
		append shapeAsBone curShape
	)
	return shapeAsBone
)

fn A2UFn_GetAllHelper = 
(
	return helpers
)

fn A2UFn_GetAllHelperExcludeParticleView = 
(
	local helperArray = #()
	for _node in helpers where (classOf _node != Particle_View) do
	(
		append helperArray _node
	)
	return helperArray
)

fn A2UFn_GetAllMesh = 
(
	local meshObjects = #()
	for geo in geometry where not (isKindOf geo Biped_Object) do
	(
		append meshObjects geo
	)
	return meshObjects
)

fn A2UFn_GetAllSkelRoot = 
(
	local rootObjects = #()
	for obj in helpers do
	(
		if obj.name == "Root" and obj.parent == undefined then 
			append rootObjects obj
	)
	return rootObjects
)

fn A2UFn_GetAllBip01Root = 
(
	--local bipedObjects = A2UFn_GetAllBipedObject()
	--local biped01Roots = #()
	--for obj in bipedObjects do
	--(
	--	if A2UFn_IsBip01RootObject(obj) then
	--	(
	--		append biped01Roots obj
	--	)
	--)
	--return biped01Roots
	local biped01Roots = #()
	for obj in geometry do
		if obj.name == "Bip01" then append biped01Roots obj
	end
	for obj in helpers do
		if obj.name == "Bip01" then append biped01Roots obj
	end
	return biped01Roots
)

fn A2UFn_GetAllChildNodes parentObj = 
(
	local selectionArray = #()
	local ret = __traversalChildNode parentObj selectionArray
	if ret then
	(
		return selectionArray
	)
	return #()
)

fn A2UFn_GetAllSkeleton skelRoot = 
(
	local selectionArray = #()
	local ret = __traversalChildSkelNode skelRoot selectionArray
	if ret then
	(
		return selectionArray
	)
	return #()
)

-- return All Skeleton Nodes
fn A2UFn_SelectAllSkeleton skelRoot = 
(
	local selectionArray = #()
	local ret = __traversalChildSkelNode skelRoot selectionArray
	if ret then
	(
		selectMore selectionArray
	)
	return ret
)

fn GetSkelAllSkeletonBipedBones root = 
(
	local nodes = A2UFn_GetAllSkeleton root
	local bipedObjects = #()
	for node in nodes where (isKindOf node Biped_Object) do
	(
		append bipedObjects node
	)
	return bipedObjects
)

fn GetSkelAllSkeletonNormalBones root = 
(
	local nodes = A2UFn_GetAllSkeleton root
	local normalBoneObjects = #()
	for node in nodes do
	(
		append normalBoneObjects node
	)
	return normalBoneObjects
)

fn A2UFn_GetAllOriginObjects = 
(
	local rootObjects = A2UFn_GetAllSkelRoot()
	local originObjects = #()
	for rootObj in rootObjects do
	(
		for _obj in rootObj.children do
		(
			if (classOf _obj == Dummy) and (_obj.name == "*origin") then
			(
				append originObjects _obj
			)
		)
	)
	return originObjects
)

fn A2UFn_GetAllIDObjects = 
(
	local rootObjects = A2UFn_GetAllSkelRoot()
	local idObjects = #()
	for rootObj in rootObjects do
	(
		for _obj in rootObj.children do
		(
			if (classOf _obj == Text) and (_obj.name == "*skelid") then
			(
				append idObjects _obj
			)
		)
	)
	return idObjects
)

fn A2UFn_GetBip01RootBySkelRoot root = 
(
	local bipRootNode = undefined
	local counter = 0
	local allBones = A2UFn_GetAllSkeleton root
	for _obj in allBones do
	(
		if A2UFn_IsBip01RootObject(_obj) then
		(
			bipRootNode = _obj
			counter = counter + 1
		)
	)
	if counter > 1 then
	(
		bipRootNode = undefined
		print("错误 一个Root下有多个Bip01点")
	)
	return bipRootNode
)

fn A2UFn_GetOriginNodeBySkelRoot root = 
(
	local originNode = undefined
	for _obj in root.children do
	(
		if (classOf _obj == Dummy) and (_obj.name == "*origin") then
		(
			originNode = _obj
		)
	)
	return originNode
)

fn A2UFn_GetIDNodeBySkelRoot root = 
(
	local skelidNode = undefined
	for _obj in root.children do
	(
		if (classOf _obj == Text) and (_obj.name == "*skelid") then
		(
			skelidNode = _obj
		)
	)
	return skelidNode
)

fn A2UFn_GetSkelIDNameBySkelRoot root = 
(
	local skelidName = ""
	for _obj in root.children do
	(
		if (classOf _obj == Text) and (_obj.name == "*skelid") then
		(
			skelidName = _obj.text
		)
	)
	return skelidName
)

fn A2UFn_CheckSkelIDNameValid skelidName = 
(
	local tokenIndex = findString skelidName "#"
	if tokenIndex == undefined then
		return false
	
	local stringArr = filterString skelidName "#"
	if stringArr.count == 1 then
	(
		if stringArr[1] != "SKEL" then
			return true
	)
	else if stringArr.count == 2 then
	(
		if stringArr[1] != "SKEL" and stringArr[2] != "ID"  then
			return true
	)
	else
	(
		return false
	)
)

-- return skelName：retArr[1] idName：retArr[2] 
fn A2UFn_GetSkelNameAndIDNameBySkelIDName skelidName = 
(
	local retArr = #("","")
	local stringArr = filterString skelidName "#"
	if A2UFn_CheckSkelIDNameValid(skelidName) then
	(
		retArr[1] = stringArr[1]
		if stringArr.count >= 2 then
		(
			retArr[2] = stringArr[2]
		)
	)
	return retArr
)

fn A2UFn_CheckMaxFileNamePrefix suffix = 
(
	local _fileName = (getFilenameFile maxFileName)
	return (findstring _fileName suffix == 1)
)

fn A2UFn_GetModelSkelAndSetName geo = 
(
	local _strarr = filterString geo.name "_"
	local ret = ""
	if _strarr.count >= 4 then
		ret = _strarr[2] + "_" + _strarr[3]
	return ret
)

-- 刀光和Custom动画名 可能需要废弃
fn A2UFn_GetAnimFinalName originalName =
(
	local finalFileName = originalName
	local pos = findString finalFileName "$"
	if pos != undefined then (
		swordLight = true
		finalFileName = replace finalFileName pos 1 ""
	)
	pos = findString finalFileName "%"
	if pos != undefined then (
		useCustom = true
		finalFileName = replace finalFileName pos 1 ""
	)

	return finalFileName
)

fn A2UFn_RotateRoot degree =
(
	if getnodebyname "Root" == undefined then
	(
		messagebox("没有找到Root点")
	)
	else
	(
		$Root.rotation = (eulerAngles 0 0 degree)
	)
)

fn A2UFn_RotateWeapon degree =
(
	local rootBone = $Root
	if rootBone == undefined then
	(
		messagebox("没有找到Root点")
	)
	else if rootBone.children.count <= 0 then
	(
		messagebox("Root点没有子骨骼?")
	)
	else
	(
		for childnode in rootBone.children do
		(
			childnode.rotation = (eulerAngles 0 0 ((quatToEuler childnode.rotation).z + degree))
		)
	)
)

-- 检查是否Skin上面还有其他修改器
fn A2UFn_CheckNoModifierOverSkinModifier geo = 
(
	if geo.modifiers[#Skin] == undefined then
		return true

	-- 顶部的修改器Index为1
	if classOf(geo.modifiers[1]) == Skin then
	(
		return true
	)
	else
	(
		messagebox(geo.name + "的Skin修改器上面有其它修改器")
		return false
	)
)

fn A2UFn_SelectAllMorphNodes = 
(
	local morphNodes = #()
	for geo in geometry do 
	(
		if A2UFn_IsBoneOrBiped geo then
			continue
		local bIsMorphNode = false
		local modifiers = geo.modifiers
		for modi in modifiers do
		(
			if classOf(modi) == Morpher then
			(
				bIsMorphNode = true
			)
		)
		if (bIsMorphNode == true) then
		(
			append morphNodes geo
		)
	)
	return morphNodes
)

fn A2UFn_SelectAllMorphAnimatedNode &onlyOneMorphAnimNames &outRangedMorphAnimNames = 
(
	local morphNodes = A2UFn_SelectAllMorphNodes()
	local animNodes = #()

	for curNode in morphNodes do
	(
		local modi = curNode.modifiers[#Morpher]
		if (modi == undefined) then
			continue
		
		local bIsAnimNode = false
		local validChannels = #()
		for i = 1 to 100 do
		(
			if ((WM3_MC_HasData curNode.morpher i) == true) then
			(
				append validChannels i
			)
		)

		for id in validChannels do
		(
			if modi[id].controller.keys.count > 0 then
			(
				bIsAnimNode = true
				if modi[id].controller.keys.count == 1 then
				(
					local _name = ("【模型】" + curNode.name + "【morph】" + modi[id].name)
					appendIfUnique onlyOneMorphAnimNames _name
				)
				for k in modi[id].controller.keys do
				(
					if k.time < animationRange.start or k.time > animationRange.end then
					(
						local _name = ("【模型】" + curNode.name + "【morph】" + modi[id].name)
						appendIfUnique outRangedMorphAnimNames _name
					)
				)
			)
		)

		if bIsAnimNode then
		(
			append animNodes curNode
		)
	)
	return animNodes
)

fn A2UFn_HaveNotBoneEnableShape rootBone = 
(
	local allSkel = A2UFn_GetAllChildNodes rootBone
	local notBoneEnabledShapes = #()
	for obj in allSkel where isKindOf obj shape do
	(
		if obj.boneEnable == false then
		(
			append notBoneEnabledShapes obj
		)
	)
	return notBoneEnabledShapes
)

-- Root/*origin关键帧数量超过1帧 或 Root/*origin位置旋转不相等
fn A2UFn_NeedCalcRootMotion rootBone = 
(
	local originBone = A2UFn_GetOriginNodeBySkelRoot rootBone
	if rootBone == undefined or originBone == undefined then return false
	
	local ret = false
	if (numkeys originBone.position.controller > 1) or (numkeys originBone.rotation.controller > 1) or (numkeys rootBone.position.controller > 1) or (numkeys rootBone.rotation.controller > 1) then
	(
		ret = true
	)
	else
	(
		if originBone.position != rootBone.position then
			ret = true
		if originBone.rotation != rootBone.rotation then
			ret = true
	)
	return ret
)

-- 返回是否把至少一个*resetlink进行了重置
fn A2UFn_TryResetAllNodeLinksByRoot rootBone = 
(
	local AllBones = A2UFn_GetAllSkeleton rootBone
	local bHaveResetLink = false
	-- 先打开auto key
	for _bone in AllBones do
	(
		if (findString _bone.name "*resetlink") == 1 and (classOf(_bone.controller) == Link_Constraint) then
		(
			for i = 1 to _bone.controller.getNumTargets() do
			(
				_bone.controller.DeleteTarget i
			)
			-- _bone.controller.addworld 0		-- 是否需要 Link to World
			bHaveResetLink = true
		)
	)
	return bHaveResetLink
)

fn A2UFn_ExportSkelAnimTransformData skelRoot fileName = 
(
	local out_file = createfile fileName
	local AllBones = A2UFn_GetAllSkeleton skelRoot

	format "Time Start:%\n" animationRange.start to:out_file
	format "Time End:%\n" animationRange.end to:out_file

	-- 先打开auto key
	for _bone in AllBones do
	(
		format "Bone Name:%\n" _bone.name to:out_file
		for i = animationRange.start to animationRange.end do
		(
			at time i
			(
				-- WORLD COORD --
				local selfMat = _bone.transform
				format "%\n" (selfMat.translationpart as string) to:out_file
				format "%\n" (selfMat.rotationpart as string) to:out_file
				format "%\n" (selfMat.scalepart as string) to:out_file
				-- format "%\n" (quattoeuler(selfMat.rotationpart) as string) to:out_file
				
				-- LOCAL COORD --
				-- local parentMat = undefined
				-- if (_bone.parent == undefined) then
				-- (
				-- 	parentMat = _bone.transform
				-- )
				-- else
				-- (
				-- 	parentMat = _bone.parent.transform
				-- )
				-- local invParentMat = inverse(parentMat)
				-- local resultMat = selfMat * invParentMat
				-- format "%\n" (resultMat.translationpart as string) to:out_file
				-- format "%\n" (resultMat.rotationpart as string) to:out_file
				-- format "%\n" quattoeuler(resultMat.rotationpart as string) to:out_file
				-- format "%\n" (resultMat.scalepart as string) to:out_file
			)
		)
	)

	close out_file
	print ("Export FBX Transform Data OK")
)

fn A2UFn_ExportSkelOriginMotionData skelOrigin fileName = 
(
	local out_file = createfile fileName
	local out_str = ""
	local animationStart = animationRange.start
	local animationEnd = animationRange.end

	for i = animationStart to animationEnd do
	(
		at time i
		(
			-- Change X/Y Order and Multiply -1 to fit the coord system in UE
			local selfMat = skelOrigin.transform
			local _x = -selfMat.translationpart.y
			_x = (floor _x+0.5) as integer
			local _y = -selfMat.translationpart.x
			_y = (floor _y+0.5) as integer
			local _z = selfMat.translationpart.z
			_z = (floor _z+0.5) as integer
			local _yaw = (quattoeuler selfMat.rotationpart).z * -1
			_yaw = (mod (floor (_yaw+0.5)) 360) as integer
			
			out_str = out_str + _x as string + "," + _y as string + "," + _z as string + "," + _yaw as string
		)
		if i < animationRange.end then
		(
			out_str = out_str + "#"	
		)
	)

	format "%" out_str to:out_file
)

fn A2UFn_GetAllClothMesh = 
(
	local clothMeshes = #()
	for geo in geometry do
	(
		local isClothMesh = matchPattern geo.name pattern:"*#cloth*"
		if isClothMesh then
		(
			append clothMeshes geo
		)
	)
	return clothMeshes
)

fn A2UFn_ApplyMaterialToAllClothMesh = 
(
	local clothMeshes = A2UFn_GetAllClothMesh()
	for geo in clothMeshes do
	(
		local newMat = StandardMaterial()
		newMat.name = geo.name
		geo.material = newMat
	)
)

fn A2UFn_CheckSkinModifierHaveBoneByName skinNode boneName = 
(
	local skinMod = skinNode.modifiers[#Skin]
	if skinMod == undefined then
		return false

	local ret = false
	subobjectLevel = 1
	modPanel.setCurrentObject skinMod
	subobjectLevel = 0
	local boneNum = skinOps.getnumberbones skinMod
	for i = 1 to boneNum do
	(
		local curBoneName = (skinOps.getBoneName skinMod i 0)
  		if curBoneName == boneName then
			ret = true
	)
	return ret
)

fn A2UFn_GetRootNodeNum = 
(
	local num = 0
	for obj in Helpers do
	(
		if obj.name == "Root" then
			num = num + 1
	)
	return num
)

fn A2UFn_GetRootNodeChildHaveAnyBipedObject = 
(
	
)

fn __CheckZeroScaleKey _Node &ZeroScaleBoneCount &ZeroScaleFrameLog = 
(
	local bHaveZeroScaleFrame = false
	if (hasProperty _Node.controller #scale) then
	(
		if (_Node.controller.scale.keys != undefined and _Node.controller.scale.keys.count > 0) then
		(
			for i = 1 to _Node.controller.scale.keys.count do
			(
				local _scale = _Node.controller.scale.keys[i].value
				if _scale.x == 0 or _scale.y == 0 or _scale.z == 0 then
				(
					print (_Node.name + " has zero scale keys at FRAME:" + _Node.controller.scale.keys[i].time as string)
					ZeroScaleFrameLog = ZeroScaleFrameLog + (_Node.name + " 在第 " + _Node.controller.scale.keys[i].time as string + " 帧为零缩放") + "\n"
					bHaveZeroScaleFrame = true
				)
			)
		)
	)
	else if(classOf(_Node.controller) == Link_Constraint) then
	(
		if (_Node.controller.link_params.scale.keys.count > 0) then
		(
			for i = 1 to _Node.controller.link_params.scale.keys.count do
			(
				local _scale = _Node.controller.link_params.scale.keys[i].value
				if _scale.x == 0 or _scale.y == 0 or _scale.z == 0 then
				(
					print (_Node.name + " has zero scale keys at FRAME:" + _Node.controller.link_params.scale.keys[i].time as string)
					ZeroScaleFrameLog = ZeroScaleFrameLog + (_Node.name + " 在第 " + _Node.controller.link_params.scale.keys[i].time as string + " 帧为零缩放") + "\n"
					bHaveZeroScaleFrame = true
				)
			)
		)
	)
	if bHaveZeroScaleFrame == true then
	(
		ZeroScaleBoneCount = ZeroScaleBoneCount + 1
	)
)

fn A2UFn_CheckZeroScaleSkelNodes skelRoot &ZeroScaleBoneCount &ZeroScaleFrameLog = 
(
	local nodes = A2UFn_GetAllSkeleton(skelRoot)
	for _node in nodes do
	(
		__CheckZeroScaleKey _node &ZeroScaleBoneCount &ZeroScaleFrameLog
	)
)

fn A2UFn_PrintNodesTransformAtFrame nodes frametime = 
(
	at time frametime
	(
		--sliderTime = frametime
		print("@Frame " + frametime as string)
	
		for curNode in nodes do
		(
			if (isKindOf curNode Biped_Object) then
			(
				local str = curNode.name
				local _position = (in coordsys world Biped.getTransform curNode #pos) as string
				local _rotation = (quatToEuler(in coordsys world Biped.getTransform curNode #rotation)) as string
				local _scale = (in coordsys world Biped.getTransform curNode #scale) as string
				str = str + _position + _rotation + _scale
				print str
			)
			else
			(
				local str = curNode.name
				local _position = (curNode.transform.translationpart) as string
				local _rotation = (quatToEuler(curNode.transform.rotationpart)) as string
				local _scale = (curNode.transform.scalepart) as string
				str = str + _position + _rotation + _scale
				print str
			)
		)
	)
)

fn A2UFn_CheckHaveSameNameNodes nodes = 
(
	local NodeNames = #()
	local NodeSameNames = #()
	for curNode in nodes do
	(
		local curNodeName = curNode.name
		if findItem NodeNames curNodeName == 0 then
		(
			append NodeNames curNodeName
		)
		else
		(
			appendIfUnique NodeSameNames curNodeName
		)
	)
	return NodeSameNames
)

fn A2UFn_SelectSameNameNodes = 
(
	clearSelection()

	local NodeSameNames = A2UFn_CheckHaveSameNameNodes()
	for SameName in NodeSameNames do
	(
		
	)
)